"
My instances represent IEEE-754 floating-point double-precision numbers.  They have about 16 digits of accuracy and their range is between plus and minus 10^307. Some valid examples are:
	
	8.0 13.3 0.3 2.5e6 1.27e-30 1.27e-31 -12.987654e12

Mainly: no embedded blanks, little e for tens power, and a digit on both sides of the decimal point.  It is actually possible to specify a radix for Float constants.  This is great for teaching about numbers, but may be confusing to the average reader:

	3r20.2 --> 6.66666666666667
	8r20.2 --> 16.25

If you don't have access to the definition of IEEE-754, you can figure out what is going on by printing various simple values in Float hex.  It may help you to know that the basic format is...
	sign		1 bit
	exponent	11 bits with bias of 1023 (16r3FF) to produce an exponent
						in the range -1023 .. +1024
				- 16r000:
					significand = 0: Float zero
					significand ~= 0: Denormalized number (exp = -1024, no hidden '1' bit)
				- 16r7FF:
					significand = 0: Infinity
					significand ~= 0: Not A Number (NaN) representation
	mantissa	53 bits, but only 52 are stored (20 in the first word, 32 in the second).  This is because a normalized mantissa, by definition, has a 1 to the right of its floating point, and IEEE-754 omits this redundant bit to gain an extra bit of precision instead.  People talk about the mantissa without its leading one as the FRACTION, and with its leading 1 as the SIGNFICAND.

The single-precision format is...
	sign		1 bit
	exponent	8 bits, with bias of 127, to represent -126 to +127
                    - 0x0 and 0xFF reserved for Float zero (mantissa is ignored)
                    - 16r7F reserved for Float underflow/overflow (mantissa is ignored)
	mantissa	24 bits, but only 23 are stored
This format is used in FloatArray (qv), and much can be learned from the conversion routines, Float asIEEE32BitWord, and Float class fromIEEE32Bit:.

Thanks to Rich Harmon for asking many questions and to Tim Olson, Bruce Cohen, Rick Zaccone and others for the answers that I have collected here.
"
Class {
	#name : 'Float',
	#superclass : 'Number',
	#classVars : [
		'DefaultComparisonPrecision',
		'E',
		'Halfpi',
		'Infinity',
		'Ln10',
		'Ln2',
		'MathApproximationEpsilon',
		'MaxVal',
		'MaxValLn',
		'MinValLogBase2',
		'NaN',
		'NegativeInfinity',
		'NegativeZero',
		'Pi',
		'RadiansPerDegree',
		'Sqrt2',
		'ThreePi',
		'Twopi'
	],
	#category : 'Kernel-Numbers',
	#package : 'Kernel',
	#tag : 'Numbers'
}

{ #category : 'instance creation' }
Float class >> basicNew [
	^BoxedFloat64 basicNew: 2
]

{ #category : 'instance creation' }
Float class >> basicNew: anInteger [
	^BoxedFloat64 basicNew: 2
]

{ #category : 'constants' }
Float class >> defaultComparisonPrecision [

	^ DefaultComparisonPrecision
]

{ #category : 'constants' }
Float class >> denormalized [
	"Answer whether implementation supports denormalized numbers (also known as gradual underflow)."

	^true
]

{ #category : 'constants' }
Float class >> e [
	"Answer the constant, E."

	^E
]

{ #category : 'constants' }
Float class >> emax [
	"Answer exponent of maximal representable value"

	^1023
]

{ #category : 'constants' }
Float class >> emin [
	"Answer exponent of minimal normalized representable value"

	^-1022
]

{ #category : 'instance creation' }
Float class >> fromIEEE32Bit: word [
	"Convert the given 32 bit word (which is supposed to be a positive 32-bit value) from
	 a 32 bit IEEE floating point representation into an actual float object (being
	 64 bits wide). Should only be used for conversion in Float32Arrays or likewise objects."

	| sign mantissa exponent delta |
	word <= 0 ifTrue:
		[^word negative
			ifTrue: [self error: 'Cannot deal with negative numbers']
			ifFalse: [self zero]].
	sign := word bitAnd: 16r80000000.
	word = sign ifTrue:
		[^self negativeZero].

	exponent := ((word bitShift: -23) bitAnd: 16rFF) - 127.
	mantissa := word bitAnd:  16r7FFFFF.

	exponent = 128 ifTrue: "Either NAN or INF"
		[^mantissa = 0
			ifTrue:
				[sign = 0
					ifTrue: [self infinity]
					ifFalse: [self negativeInfinity]]
			ifFalse: [self nan]].

	exponent = -127 ifTrue:
		"gradual underflow (denormalized number)
		 Remove first bit of mantissa and adjust exponent"
		[delta := mantissa highBit.
		 mantissa := (mantissa bitAnd: (1 bitShift: delta - 1) - 1) bitShift: 24 - delta.
		 exponent := exponent + delta - 23].

	"Create new float"
	^(self basicNew: 2)
		basicAt: 1 put: ((sign bitOr: (1023 + exponent bitShift: 20)) bitOr: (mantissa bitShift: -3));
		basicAt: 2 put: ((mantissa bitAnd: 7) bitShift: 29);
		* 1.0 "reduce to SmallFloat64 if possible"
]

{ #category : 'instance creation' }
Float class >> fromIEEE64Bit: doubleWord [

    ^ (self new: 2) basicAt: 1 put: (doubleWord bitShift: -32); basicAt: 2 put: (doubleWord bitAnd: 16rFFFFFFFF); yourself
]

{ #category : 'instance creation' }
Float class >> fromIEEE64BitWord: anInteger [
	"Convert the given 64 bit word from a 64 bit IEEE floating point representation
	into an actual float object.
	Should only be used for conversion in Float64Arrays or likewise objects."

	| value |
	value := self basicNew: 2.
	value
		basicAt: 1 put: (anInteger bitShift: -32);
		basicAt: 2 put: (anInteger bitAnd: 16rFFFFFFFF).
	^value isFinite
		ifTrue: [value * 1.0] "reduce to SmallFloat64 if possible"
		ifFalse: [value]
]

{ #category : 'constants' }
Float class >> halfPi [
	^ Halfpi
]

{ #category : 'constants' }
Float class >> infinity [
	"Answer the value used to represent an infinite magnitude"

	^ Infinity
]

{ #category : 'class initialization' }
Float class >> initialize [
	"Float initialize"
	"Constants from Computer Approximations, pp. 182-183:
		Pi = 3.14159265358979323846264338327950288
		Pi/2 = 1.57079632679489661923132169163975144
		Pi*2 = 6.28318530717958647692528676655900576
		Pi/180 = 0.01745329251994329576923690768488612
		2.0 ln = 0.69314718055994530941723212145817657
		2.0 sqrt = 1.41421356237309504880168872420969808"

	Pi := 3.14159265358979323846264338327950288.
	Halfpi := Pi / 2.0.
	Twopi := Pi * 2.0.
	ThreePi := Pi * 3.0.
	RadiansPerDegree := Pi / 180.0.

	Ln2 := 0.69314718055994530941723212145817657.
	Ln10 := 10.0 ln.
	Sqrt2 := 1.41421356237309504880168872420969808.
	E := 2.718281828459045235360287471353.

	"Defines precision of approximated mathematical functions such as trigonometric functions.
	Use a small enough epsilon value to make approximations as good as possible.
	This one should probably be removed and we should use DefaultComparisonPrecision but I'm not sure it's that simple to remove a class var of Float."
	MathApproximationEpsilon := 0.000000000001.

	"Default precision used for comparing two float numbers.
	Using value described in Numerical Recipes, 3rd edition, Section 5.7, which is pages 229-230 corresponding to the square root of the machine epsilon"
	DefaultComparisonPrecision := 1.4901161193847656e-8. "This is the result of `self machineEpsilon sqrt ` but the bootstrap does not work if we do not put the constant directly. This is due to the fact that #sqrt is loaded after this value is initialized."

	MaxVal := 1.7976931348623157e308.
	MaxValLn := 709.782712893384.
	MinValLogBase2 := -1074.

	Infinity := MaxVal * MaxVal.
	NegativeInfinity := 0.0 - Infinity.
	NaN := Infinity - Infinity.
	NegativeZero := 1.0 / Infinity negated
]

{ #category : 'testing' }
Float class >> isAbstract [

	^ self == Float
]

{ #category : 'constants' }
Float class >> machineEpsilon [
	"Answer the machine epsilon or macheps, defined by Wikipedia (https://en.wikipedia.org/wiki/Machine_epsilon) as:

	*an upper bound on the relative approximation error due to rounding in floating point arithmetic*

	Compute it as the difference between 1.0 and previous representable value"

	^1.0 timesTwoPower: 1 - self precision
]

{ #category : 'constants' }
Float class >> maxExactInteger [
	"Answer the biggest integer such that it is exactly represented in a float, and all smaller integers also are"
	^1 bitShift: self precision
]

{ #category : 'constants' }
Float class >> nan [
	"Answer the canonical value used to represent Not-A-Number"

	^ NaN
]

{ #category : 'constants' }
Float class >> negativeInfinity [
	"Answer the value used to represent a negative infinite magnitude"

	^ NegativeInfinity
]

{ #category : 'constants' }
Float class >> negativeZero [

	^ NegativeZero
]

{ #category : 'constants' }
Float class >> one [

	^1.0
]

{ #category : 'constants' }
Float class >> pi [
	"Answer the constant, Pi."

	^Pi
]

{ #category : 'constants' }
Float class >> precision [
	"Answer the apparent precision of the floating point representation.
	That is the maximum number of radix-based digits (bits if radix=2) representable in floating point without round off error.
	Technically, 52 bits are stored in the representation, and normalized numbers have an implied leading 1 that does not need to be stored.
	Note that denormalized floating point numbers don't have the implied leading 1, and thus gradually loose precision.
	This format conforms IEEE 754 double precision standard."

	^53
]

{ #category : 'constants' }
Float class >> radix [
	"Answer the radix used for internal floating point representation."

	^2
]

{ #category : 'instance creation' }
Float class >> readFrom: aStream [
	"Answer a new Float as described on the stream, aStream."

	^(super readFrom: aStream) asFloat
]

{ #category : 'instance creation' }
Float class >> readFrom: aStream ifFail: aBlock [
	"Answer a new Float as described on the stream, aStream."

	^(super readFrom: aStream ifFail: [^aBlock value]) asFloat
]

{ #category : 'constants' }
Float class >> threePi [

	^ ThreePi
]

{ #category : 'constants' }
Float class >> twoPi [

	^ Twopi
]

{ #category : 'constants' }
Float class >> zero [
	^ 0.0
]

{ #category : 'arithmetic' }
Float >> abs [
	"This is faster than using Number abs and works for negativeZero."
	^ self <= 0.0
		ifTrue: [0.0 - self]
		ifFalse: [self]
]

{ #category : 'converting' }
Float >> adaptToFraction: rcvr andCompare: selector [
	"If I am involved in comparison with a Fraction, convert myself to a
	Fraction. This way, no bit is lost and comparison is exact."

	self isFinite
		ifFalse: [
			selector == #= ifTrue: [^false].
			selector == #~= ifTrue: [^true].
			self isNaN ifTrue: [^ false].
			(selector = #< or: [selector = #'<='])
				ifTrue: [^ self positive].
			(selector = #> or: [selector = #'>='])
				ifTrue: [^ self positive not].
			^self error: 'unknow comparison selector'].

	"Try to avoid asTrueFraction because it can cost"
	selector == #= ifTrue: [
		rcvr denominator isPowerOfTwo ifFalse: [^false]].
	selector == #~= ifTrue: [
		rcvr denominator isPowerOfTwo ifFalse: [^true]].

	^ rcvr perform: selector with: self asTrueFraction
]

{ #category : 'converting' }
Float >> adaptToFraction: rcvr andSend: selector [
	"If I am involved in arithmetic with a Fraction, convert it to a Float."
	^ rcvr asFloat perform: selector with: self
]

{ #category : 'converting' }
Float >> adaptToInteger: rcvr andCompare: selector [
	"If I am involved in comparison with an Integer, convert myself to a
	Fraction. This way, no bit is lost and comparison is exact."

	self isFinite ifFalse: [
		selector == #= ifTrue: [ ^ false ].
		selector == #'~=' ifTrue: [ ^ true ].
		self isNaN ifTrue: [ ^ false ].
		(selector = #< or: [ selector = #'<=' ]) ifTrue: [ ^ self positive ].
		(selector = #> or: [ selector = #'>=' ]) ifTrue: [ ^ self positive not ].
		^ self error: 'unknow comparison selector' ].

	"Try to avoid asTrueFraction because it can cost"
	selector == #= ifTrue: [ self fractionPart = 0.0 ifFalse: [ ^ false ] ].
	selector == #'~=' ifTrue: [ self fractionPart = 0.0 ifFalse: [ ^ true ] ].
	selector == #< ifTrue: [ ^ self > rcvr ].
	selector == #> ifTrue: [ ^ self < rcvr ].
	selector == #'<=' ifTrue: [ ^ self >= rcvr ].
	selector == #'>=' ifTrue: [ ^ self <= rcvr ].

	^ rcvr perform: selector with: self asTrueFraction
]

{ #category : 'converting' }
Float >> adaptToInteger: rcvr andSend: selector [
	"If I am involved in arithmetic with an Integer, convert it to a Float."
	^ rcvr asFloat perform: selector with: self
]

{ #category : 'converting' }
Float >> asApproximateFraction [
	"Answer a Fraction approximating the receiver. This conversion uses the
	continued fraction method to approximate a floating point number."

	^ self asApproximateFractionAtOrder: 0
]

{ #category : 'converting' }
Float >> asApproximateFractionAtOrder: maxOrder [
	"Answer a Fraction approximating the receiver. This conversion uses the
	continued fraction method to approximate a floating point number. If maxOrder
	is zero, use maximum order"

	| num1 denom1 num2 denom2 int frac newD temp order |
	num1 := self asInteger.	"The first of two alternating numerators"
	denom1 := 1.		"The first of two alternating denominators"
	num2 := 1.		"The second numerator"
	denom2 := 0.		"The second denominator--will update"
	int := num1.		"The integer part of self"
	frac := self fractionPart.		"The fractional part of self"
	order := maxOrder = 0 ifTrue: [-1] ifFalse: [maxOrder].
	[frac = 0 or: [order = 0] ]
		whileFalse:
			["repeat while the fractional part is not zero and max order is not reached"
			order := order - 1.
			newD := 1.0 / frac.			"Take reciprocal of the fractional part"
			int := newD asInteger.		"get the integer part of this"
			frac := newD fractionPart.	"and save the fractional part for next time"
			temp := num2.				"Get old numerator and save it"
			num2 := num1.				"Set second numerator to first"
			num1 := num1 * int + temp.	"Update first numerator"
			temp := denom2.				"Get old denominator and save it"
			denom2 := denom1.			"Set second denominator to first"
			denom1 := int * denom1 + temp.		"Update first denominator"
			10000000000.0 < denom1
				ifTrue:
					["Is ratio past float precision?  If so, pick which
					of the two ratios to use"
					num2 = 0.0
						ifTrue: ["Is second denominator 0?"
								^ Fraction numerator: num1 denominator: denom1].
					^ Fraction numerator: num2 denominator: denom2]].
	"If fractional part is zero, return the first ratio"
	^ denom1 = 1
		ifTrue: ["Am I really an Integer?"
				num1 "Yes, return Integer result"]
		ifFalse: ["Otherwise return Fraction result"
				Fraction numerator: num1 denominator: denom1]
]

{ #category : 'converting' }
Float >> asFloat [
	"Answer the receiver itself."

	^self
]

{ #category : 'converting' }
Float >> asFraction [
	^ self asTrueFraction
]

{ #category : 'converting' }
Float >> asScaledDecimal [

	"Answer a scaled decimal number approximating the receiver.

	IEEE 754 double precision numbers use 53 bits to encode mantissa. This means
	that the maximum amount of decimal digits that can be represented is log10(2^53).

	Due to the fact that at least one of the decimal digits has to be placed to
	the left of the decimal point, the scale was set to 15 - 1 = 14."

	^ self asScaledDecimal: 14
]

{ #category : 'converting' }
Float >> asTrueFraction [
	" Answer a fraction that EXACTLY represents self,
	  a double precision IEEE floating point number.
	  Floats are stored in the same form on all platforms.
	  (Does handle gradual underflow but not NANs.)
	  By David N. Smith with significant performance
	  improvements by Luciano Esteban Notarfrancesco.
	  (Version of 11April97)"
	| signexp positive expPart exp fraction fractionPart signedFraction result zeroBitsCount |
	self isInfinite ifTrue: [self error: 'Cannot represent infinity as a fraction'].
	self isNaN ifTrue: [self error: 'Cannot represent Not-a-Number as a fraction'].


	" Extract the sign and the biased exponent "
	signexp := (self basicAt: 1) bitShift: -20.
	positive := (signexp bitAnd: 16r800) = 0.
	expPart := signexp bitAnd: 16r7FF.

	" Extract fractional part; answer 0 if this is a true 0.0 value "
	fractionPart := (((self basicAt: 1) bitAnd: 16rFFFFF) bitShift: 32)+ (self basicAt: 2).
	( expPart=0 and: [ fractionPart=0 ] ) ifTrue: [ ^ 0  ].

	" Replace omitted leading 1 in fraction unless gradual underflow"
	fraction := expPart = 0
		ifTrue: [fractionPart bitShift: 1]
		ifFalse: [fractionPart bitOr: 16r0010000000000000].
	signedFraction := positive ifTrue: [fraction] ifFalse: [fraction negated].

	"Unbias exponent: 16r3FF is bias; 52 is fraction width"
	exp := 16r3FF + 52 - expPart.

	" Form the result. When exp>52, the exponent is adjusted by
	  the number of trailing zero bits in the fraction to minimize
	  the (huge) time otherwise spent in #gcd:. "
	exp negative
		ifTrue: [
			result := signedFraction bitShift: exp negated ]
		ifFalse:	[
			zeroBitsCount := fraction lowBit - 1.
			exp := exp - zeroBitsCount.
			exp <= 0
				ifTrue: [
					zeroBitsCount := zeroBitsCount + exp.
					"exp := 0."   " Not needed; exp not
refernced again "
					result := signedFraction bitShift:
zeroBitsCount negated ]
				ifFalse: [
					result := Fraction
						numerator: (signedFraction
bitShift: zeroBitsCount negated)
						denominator: (1 bitShift:
exp) ] ].

	"Low cost validation omitted after extensive testing"
	"(result asFloat = self) ifFalse: [self error: 'asTrueFraction validation failed']."
	^ result
]

{ #category : 'accessing' }
Float >> at: index [
	^self basicAt: index
]

{ #category : 'accessing' }
Float >> at: index put: value [
	^self basicAt: index put: value
]

{ #category : 'accessing' }
Float >> basicAt: index [
	"Primitive. Assumes receiver is indexable. Answer the value of an
	indexable element in the receiver. Fail if the argument index is not an
	Integer or is out of bounds. Essential. Do not override in a subclass. See
	Object documentation whatIsAPrimitive.

	This version of basicAt: is specifically for floats, answering the most significant
	word for index 1 and the least significant word for index 2. This allows the VM
	to store floats in whatever order it chooses while it appears to the image that
	they are always in big-endian/PowerPC order."

	<primitive: 38>
	^super basicAt: index
]

{ #category : 'accessing' }
Float >> basicAt: index put: value [
	"Primitive. Assumes receiver is indexable. Store the second argument
	value in the indexable element of the receiver indicated by index. Fail
	if the index is not an Integer or is out of bounds. Or fail if the value is
	not of the right type for this kind of collection. Answer the value that
	was stored. Essential. Do not override in a subclass. See Object
	documentation whatIsAPrimitive.

	This version of basicAt: is specifically for floats, answering the most significant
	word for index 1 and the least significant word for index 2. This allows the VM
	to store floats in whatever order it chooses while it appears to the image that
	they are always in big-endian/PowerPC order."

	<primitive: 39>
	^super basicAt: index put: value
]

{ #category : 'copying' }
Float >> deepCopy [

	^self copy
]

{ #category : 'mathematical functions' }
Float >> exponent [
	^ self subclassResponsibility
]

{ #category : 'comparing' }
Float >> hash [
	"Hash is reimplemented because = is implemented. Both words of the float are used; 8 bits are removed from each end to clear most of the exponent regardless of the byte ordering. (The bitAnd:'s ensure that the intermediate results do not become a large integer.) Slower than the original version in the ratios 12:5 to 2:1 depending on values. (DNS, 11 May, 1997)"

	(self isFinite and: [self fractionPart = 0.0]) ifTrue: [^self truncated hash].
	^ (((self basicAt: 1) bitAnd: 16r00FFFF00) +
	   ((self basicAt: 2) bitAnd: 16r00FFFF00)) bitShift: -8
]

{ #category : 'testing' }
Float >> isFinite [
	"simple, byte-order independent test for rejecting Not-a-Number and (Negative)Infinity"

	^(self - self) = 0.0
]

{ #category : 'testing' }
Float >> isFloat [
	^ true
]

{ #category : 'testing' }
Float >> isInfinite [
	"Return true if the receiver is positive or negative infinity."

	^ self = Infinity or: [self = NegativeInfinity]
]

{ #category : 'testing' }
Float >> isLiteral [
	"There is no literal representation of NaN.
	However, there are literal representations of Infinity, like 1.0e1000.
	But since they are not able to print properly, only case of finite Float is considered."

	^self isFinite
]

{ #category : 'testing' }
Float >> isNaN [
	"simple, byte-order independent test for Not-a-Number"

	^ self ~= self
]

{ #category : 'testing' }
Float >> isPowerOfTwo [
	"Return true if the receiver is an integral power of two.
	Floats never return true here."
	^false
]

{ #category : 'testing' }
Float >> isSelfEvaluating [
    ^true
]

{ #category : 'testing' }
Float >> isZero [
	^self = 0.0
]

{ #category : 'comparing' }
Float >> literalEqual: other [

	^ (super literalEqual: other) and: [ self isZero not or: [ self signBit = other signBit ] ]
]

{ #category : 'arithmetic' }
Float >> negated [
	"Answer a Number that is the negation of the receiver.
	Implementation note: this version cares of negativeZero."

	^-1.0 * self
]

{ #category : 'copying' }
Float >> shallowCopy [

	^self - 0.0
]

{ #category : 'mathematical functions' }
Float >> signBit [
	"Answer 1 if the receiver has sign bit set (including case of IEEE-754 negative-zero).
	Answer 0 otherwise"

	^((self at: 1) bitShift: -31)
]

{ #category : 'mathematical functions' }
Float >> timesTwoPower: anInteger [
	^ self subclassResponsibility
]
